﻿using Prism.Ioc;
using StarryEdge.Core;
using StarryEdge.Core.Device;
using StarryEdge.Core.Models;
using StarryEdge.Core.Parameter;
using StarryEdge.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace StarryEdge.Domains
{
    public class TaskEntity
    {
        public string ServiceName { get; set; }
        public string Key { get; set; }
        public bool IsRun { get; set; }
        private TaskHandleModel _taskHandle;
        private object _parameter;
        private IStarryEdgeLog _starryEdgeLog;
        private IDialogHost _dialogHost;
        private IContainerProvider _containerProvider;
        //private List<ISubtask<int>> _subtaskInt = new List<ISubtask<int>>();
        //private List<ISubtask<string>> _subtaskString = new List<ISubtask<string>>();

        public TaskEntity(IStarryEdgeLog starryEdgeLog, IDialogHost dialogHost, IContainerProvider containerProvider) 
        { 
            _starryEdgeLog = starryEdgeLog;
            _dialogHost = dialogHost;
            _containerProvider = containerProvider;
        }

        public void SetObject(object obj, TaskHandleModel taskHandle)
        {
            _taskHandle = taskHandle;
            _parameter = obj;
            //var taskObject = _taskHandle.TaskObject.GetType().GetMethod("Handle").GetCustomAttributes();
            //foreach (var item in taskObject)
            //{
            //    Type type = item.GetType();
            //    if (type.Name != "AsyncStateMachineAttribute" && type.Name != "NullableContextAttribute")
            //    {
            //        Type type1;
            //        if (obj is HandleContext<int>)
            //        {
            //            type1 = type.MakeGenericType(typeof(int));
            //        }
            //        else
            //        {
            //            type1 = type.MakeGenericType(typeof(string));
            //        }
            //        object subtask = Activator.CreateInstance(type1);
            //        if (subtask is ISubtask<int> subtaskInt)
            //        {
            //            _subtaskInt.Add(subtaskInt);
            //        }
            //        else if (subtask is ISubtask<string> subtaskString)
            //        {
            //            _subtaskString.Add(subtaskString);
            //        }
            //    }
            //}
        }

        public void Handle<T>(IPLC<T> plc)
        {
            if (WriteInExecution(plc, (HandleContext<T>)_parameter))
            {
                //if (_subtaskInt.Count > 0)
                //{
                //    foreach (var item in _subtaskInt)
                //    {
                //        if (!item.Handle((HandleContext<int>)_parameter, _starryEdgeLog, _dialogHost, plc, _containerProvider.Resolve<ISystemConfigParameter>()))
                //        {
                //            return;
                //        }
                //    }
                //}
                //if (_subtaskString.Count > 0)
                //{
                //    foreach (var item in _subtaskString)
                //    {
                //        if (!item.Handle((HandleContext<string>)_parameter, _starryEdgeLog, _dialogHost, plc, _containerProvider.Resolve<ISystemConfigParameter>()))
                //        {
                //            return;
                //        }
                //    }
                //}
                _taskHandle.Handle.Invoke(_taskHandle.TaskObject, new object[] { _parameter });
                WriteComplete(plc, (HandleContext<T>)_parameter);
            }
        }

        private bool WriteInExecution<T>(IPLC<T> plc, HandleContext<T> context)
        {
            if (context.TaskName.Contains("设备状态") || context.IsScheduledTask)
            {
                return true;
            }
            _starryEdgeLog.LogRun($"[{context.ServiceName}]-[{context.TaskName}]-[{context.Address_Signal}] 收到触发信号", Core.Enums.LogLevel.Success);
            int count = 0;
            while (count < 3)
            {
                if (plc.WriteSingle(context.Address_Signal, (short)99, 0))
                {
                    _starryEdgeLog.LogRun($"[{context.ServiceName}]-[{context.TaskName}]-[{context.Address_Signal}] 启动地址写入 99 成功", Core.Enums.LogLevel.Success);
                    return true;
                }
                count++;
            }
            _starryEdgeLog.LogRun($"[{context.ServiceName}]-[{context.TaskName}]-[{context.Address_Signal}] 启动地址写入 99 失败", Core.Enums.LogLevel.Warning);
            return false;
        }

        private void WriteComplete<T>(IPLC<T> plc, HandleContext<T> context)
        {
            if (context.TaskName.Contains("设备状态") || context.IsScheduledTask)
            {
                return;
            }
            int count = 0;
            while (count < 3)
            {
                if (plc.WriteSingle(context.Address_Signal, (short)2, 0))
                {
                    _starryEdgeLog.LogRun($"[{context.ServiceName}]-[{context.TaskName}]-[{context.Address_Signal}] 启动地址写入 2 成功", Core.Enums.LogLevel.Success);
                    return;
                }
                count++;
            }
            _starryEdgeLog.LogRun($"[{context.ServiceName}]-[{context.TaskName}]-[{context.Address_Signal}] 启动地址写入 2 失败", Core.Enums.LogLevel.Warning);
        }

    }
}
